#ifndef __UIBASE_H__
#define __UIBASE_H__


#pragma once

namespace DuiLib
{
    /////////////////////////////////////////////////////////////////////////////////////
    //

    #define UI_WNDSTYLE_CONTAINER  (0)
    #define UI_WNDSTYLE_FRAME      (WS_VISIBLE | WS_OVERLAPPEDWINDOW)
    #define UI_WNDSTYLE_CHILD      (WS_VISIBLE | WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN)
    #define UI_WNDSTYLE_DIALOG     (WS_VISIBLE | WS_POPUPWINDOW | WS_CAPTION | WS_DLGFRAME | WS_CLIPSIBLINGS | WS_CLIPCHILDREN)

    #define UI_WNDSTYLE_EX_FRAME   (WS_EX_WINDOWEDGE)
    #define UI_WNDSTYLE_EX_DIALOG  (WS_EX_TOOLWINDOW | WS_EX_DLGMODALFRAME)

    #define UI_CLASSSTYLE_CONTAINER  (0)
    #define UI_CLASSSTYLE_FRAME      (CS_VREDRAW | CS_HREDRAW)
    #define UI_CLASSSTYLE_CHILD      (CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS | CS_SAVEBITS)
    #define UI_CLASSSTYLE_DIALOG     (CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS | CS_SAVEBITS)


    /////////////////////////////////////////////////////////////////////////////////////
    //
    #ifndef ASSERT
    #define ASSERT(expr)  _ASSERTE(expr)
    #endif

    #ifdef _DEBUG
    #ifndef DUITRACE
    #define DUITRACE DUI__Trace
    #endif
    #define DUITRACEMSG DUI__TraceMsg
    #else
    #ifndef DUITRACE
    #define DUITRACE
    #endif
    #define DUITRACEMSG _T("")
    #endif

    void DUILIB_API DUI__Trace(LPCTSTR pstrFormat, ...);
    LPCTSTR DUILIB_API DUI__TraceMsg(UINT uMsg);

    /////////////////////////////////////////////////////////////////////////////////////
    //

    class DUILIB_API CNotifyPump
    {
    public:
        bool AddVirtualWnd(CDuiString strName, CNotifyPump* pObject);
        bool RemoveVirtualWnd(CDuiString strName);
        void NotifyPump(TNotifyUI& msg);
        bool LoopDispatch(TNotifyUI& msg);
        DUI_DECLARE_MESSAGE_MAP()
    private:
        CDuiStringPtrMap m_VirtualWndMap;
    };

    class DUILIB_API CWindowWnd
    {
    public:
        CWindowWnd();

        // 获取窗体句柄
        HWND GetHWND() const;
        operator HWND() const;

        // 注册窗体
        bool RegisterWindowClass();
        // 注册超类化窗体
        bool RegisterSuperClass();

        // 创建
        HWND Create(HWND hwndParent, LPCTSTR pstrName, DWORD dwStyle, DWORD dwExStyle, const RECT rc, HMENU hMenu = NULL);
        HWND Create(HWND hwndParent, LPCTSTR pstrName, DWORD dwStyle, DWORD dwExStyle, int x = CW_USEDEFAULT, int y = CW_USEDEFAULT, int cx = CW_USEDEFAULT, int cy = CW_USEDEFAULT, HMENU hMenu = NULL);
        HWND CreateDuiWindow(HWND hwndParent, LPCTSTR pstrWindowName, DWORD dwStyle = 0, DWORD dwExStyle = 0);

        // 子类化
        HWND Subclass(HWND hWnd);
        // 取消子类化
        void UnSubclass();

        // 设置窗体的显示状态
        void ShowWindow(bool bShow = true, bool bTakeFocus = true);
        // 模态显示
        UINT ShowModal();
        // 关闭
        void Close(UINT nRet = IDOK);
        // 窗体居中
        void CenterWindow();
        // 设置图标
        void SetIcon(UINT nRes);
        // 发送消息（同步）
        LRESULT SendMessage(UINT uMsg, WPARAM wParam = 0, LPARAM lParam = 0L);
        // 发送消息（异步-消息队列）
        LRESULT PostMessage(UINT uMsg, WPARAM wParam = 0, LPARAM lParam = 0L);
        // 调整窗体大小
        void ResizeClient(int cx = -1, int cy = -1);

    protected:
        // 获取窗体类名
        virtual LPCTSTR GetWindowClassName() const = 0;
        virtual LPCTSTR GetSuperClassName() const;

        // 获取风格样式
        virtual UINT GetClassStyle() const;
        // 消息处理入口
        virtual LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam);
        // 窗体销毁时的消息处理
        virtual void OnFinalMessage(HWND hWnd);

        // 窗体处理函数
        static LRESULT CALLBACK __WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
        static LRESULT CALLBACK __ControlProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

    protected:
        // 窗体句柄
        HWND m_hWnd;
        // 原始的窗体处理函数(子类化或超类化)
        WNDPROC m_OldWndProc;
        // 是否子类化
        bool m_bSubclassed;
    };

} // namespace DuiLib

#endif // __UIBASE_H__
